﻿using System.Collections.Generic;
using UnityEngine;
using 凌依.工具库.U3D空间计算;

namespace 凌依.工具库.U3D渲染 
{
    [System.Serializable]
    public class 射线视觉
    {
        public Material 射线材质;
        public Transform 物体;
        public int 射线数量;
        public float 射线间隔角度;
        public float 射线长度;
        public float 射线宽度;
        public Color 射线颜色;
        public bool 显示射线;
        public bool _2D;
        public List<LineRenderer> 射线列表;

        /// <summary>
        /// 必须运行
        /// </summary>
        /// <param name="材质">射线材质</param>
        /// <param name="数量">射线数量</param>
        /// <param name="间隔角度">射线间隔角度</param>
        /// <param name="长度">射线长度</param>
        /// <param name="显示射线"></param>
        /// <param name="_2D"></param>
        public 射线视觉(Material 材质, int 数量, float 间隔角度, float 长度, float 宽度, Color 颜色, bool 显示射线, bool _2D, Transform 物体)
        {
            射线材质 = 材质;
            this.物体 = 物体;
            射线数量 = 数量;
            射线间隔角度 = 间隔角度;
            射线长度 = 长度;
            射线宽度 = 宽度;
            射线颜色 = 颜色;
            this.显示射线 = 显示射线;
            this._2D = _2D;
            生成射线();
        }
        /// <summary>
        /// 用于初始化射线
        /// </summary>
        public void 生成射线()
        {
            try
            {
                foreach (var item in 射线列表)
                    Object.DestroyImmediate(item.gameObject);
                
            }
            catch
            {
                射线列表 = new List<LineRenderer>();
            }




            射线列表 = new List<LineRenderer>();
            for (int i = 0; i < 射线数量; i++)
            {
                LineRenderer lr = new GameObject("射线" + i).AddComponent<LineRenderer>();
                lr.transform.SetParent(物体);
                lr.transform.localPosition = Vector3.zero;
                lr.transform.localRotation = Quaternion.identity;
                lr.startWidth = 射线宽度;
                lr.endWidth = 射线宽度;
                lr.material = 射线材质;
                lr.startColor = 射线颜色;
                lr.endColor = 射线颜色;
                lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
                lr.receiveShadows = false;
                射线列表.Add(lr);
            }
        }
        /// <summary>
        /// 反馈视觉信息,请先调用初始化在调用本函数
        /// </summary>
        /// <param name="碰撞标签"></param>
        /// <returns></returns>
        public List<float> 视觉信息(string[] 碰撞标签)
        {
            float 最小角度 = -射线数量 / 2 * 射线间隔角度;
            List<float> 视野输入 = new List<float>();
            if (_2D)
            {
                //2d
                for (int i = 0; i < 射线数量; i++)
                {
                    射线列表[i].gameObject.SetActive(显示射线);
                    射线列表[i].SetPosition(0, 物体.position);
                    Vector3 方向 = Quaternion.AngleAxis(最小角度 + i * 射线间隔角度, 物体.forward) * 物体.up;

                    RaycastHit2D 射线 = Physics2D.Raycast(空间计算.坐标转换(物体.position), 空间计算.坐标转换(方向), 射线长度);
                    float 距离 = Mathf.Pow(1 - 射线.distance / 射线长度, 2);
                    if (射线.transform != null)
                    {
                        bool ls = false;
                        foreach (string n in 碰撞标签)
                        {
                            if (射线.transform.tag == n)
                            {
                                ls = true;
                                视野输入.Add(距离);
                                break;
                            }
                        }

                        if (ls)
                            射线列表[i].SetPosition(1, 射线.point);
                        else
                        {
                            视野输入.Add(0);
                            射线列表[i].SetPosition(1, 物体.position + 方向 * 射线长度);
                        }

                    }
                    else
                    {
                        视野输入.Add(0);
                        射线列表[i].SetPosition(1, 物体.position + 方向 * 射线长度);
                    }
                }

            }
            else
            {
                //3d
                for (int i = 0; i < 射线数量; i++)
                {
                    射线列表[i].gameObject.SetActive(显示射线);
                    射线列表[i].SetPosition(0, 物体.position);
                    Vector3 方向 = Quaternion.AngleAxis(最小角度 + i * 射线间隔角度, 物体.up) * 物体.forward;
                    RaycastHit hitInfo;
                    if (Physics.Raycast(物体.position, 方向, out hitInfo, 射线长度))
                    {
                        float pd = Mathf.Pow(1 - hitInfo.distance / 射线长度, 2);



                        bool ls = false;
                        foreach (string n in 碰撞标签)
                        {
                            if (hitInfo.transform.tag == n)
                            {
                                视野输入.Add(pd);
                                ls = true;
                                break;
                            }
                        }


                        if (ls)
                            射线列表[i].SetPosition(1, hitInfo.point);
                        else
                        {
                            视野输入.Add(0);
                            射线列表[i].SetPosition(1, 物体.position + 方向 * 射线长度);
                        }



                    }
                    else
                    {
                        视野输入.Add(0);
                        射线列表[i].SetPosition(1, 物体.position + 方向 * 射线长度);
                    }
                }
            }
            return 视野输入;
        }

    }
}
